﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using System.Globalization;

namespace FanaticGene.AvaloniaMaid.Core.Analyzer
{
    public class CodeAnalyzer
    {
        ///<summary>获得包含指定代码行的类型域。</summary>
        public ClassDomain GetClassDomain(string projectName, string codeFilePath, string currentLineStr)
        {
            if (!int.TryParse(currentLineStr, out var currentLine)) return null;
            currentLine = currentLine - 1; // to 0 base
            using var fs = new FileStream(codeFilePath, FileMode.Open, FileAccess.Read);
            using var sr = new StreamReader(fs);

            var tree = CSharpSyntaxTree.ParseText(sr.ReadToEnd());

            if (tree == null) return null;

            var descendantsNodes = tree.GetRoot().DescendantNodes();
            var nodes = descendantsNodes.OfType<MemberDeclarationSyntax>().Where(n => n is PropertyDeclarationSyntax || n is FieldDeclarationSyntax);
            var targetNode = nodes.FirstOrDefault(n => n.GetLocation().GetLineSpan().StartLinePosition.Line == currentLine);

            if (targetNode == null) return null;
            var classDomain = CreateClassDomain(targetNode);
            if (classDomain != null) classDomain.ProjectName = projectName;
            return classDomain;
        }

        private ClassDomain CreateClassDomain(MemberDeclarationSyntax declarationNode)
        {
            var classNode = declarationNode.Parent as ClassDeclarationSyntax;
            if (classNode == null) return null;

            if (declarationNode is PropertyDeclarationSyntax)
            {
                var propNode = declarationNode as PropertyDeclarationSyntax;
                var identifier = propNode.Identifier.Text;
                return new ClassDomain()
                {
                    ClassName = classNode.Identifier.Text,
                    MemberType = propNode.Type.ToString(),
                    MemberName = ToFirstUpper(identifier)
                };
            }
            else if (declarationNode is FieldDeclarationSyntax)
            {
                var fieldNode = declarationNode as FieldDeclarationSyntax;
                var identifier = fieldNode.Declaration.Variables[0].Identifier.Text.TrimStart('_');
                return new ClassDomain()
                {
                    ClassName = classNode.Identifier.Text,
                    MemberType = fieldNode.Declaration.Type.ToString(),
                    MemberName = ToFirstUpper(identifier)
                };
            }

            return null;
        }

        public string ToFirstUpper(string text)
        {
            if (string.IsNullOrWhiteSpace(text)) return string.Empty;
            return text[0] + text.Substring(1);
        }

    }
}
